/**
 */
package org.thss.petri.model.impl;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.emf.ecore.EClass;
import org.thss.petri.model.Arc;
import org.thss.petri.model.PetriFactory;
import org.thss.petri.model.PetriPackage;
import org.thss.petri.model.Place;
import org.thss.petri.model.Token;
import org.thss.petri.model.Transition;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Transition</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.thss.petri.model.impl.TransitionImpl#isEnabled <em>Enabled</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class TransitionImpl extends NodeImpl implements Transition {
	/**
	 * The default value of the '{@link #isEnabled() <em>Enabled</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isEnabled()
	 * @generated
	 * @ordered
	 */
	protected static final boolean ENABLED_EDEFAULT = false;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected TransitionImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return PetriPackage.Literals.TRANSITION;
	}

	/**
	 * Returns whether a transition can fire.
	 * @generated NOT
	 */
	public boolean isEnabled() {
		if (getIncomings().size() == 0) {
			return false;
		}
		
		for (Arc arc : getIncomings()) {
			Place place = (Place) arc.getSource();
			if (place.getTokens().size() < arc.getWeight()) {
				return false;
			}
		}
		return true;
	}

	/**
	 * Fire the transition.
	 * @generated NOT
	 */
	public void fire() {
		List<Token> tokens = new ArrayList<Token>();
		for (Arc arc : getIncomings()) {
			Place place = (Place) arc.getSource();
			int count = arc.getWeight();
			for (int i = 0; i < count; i++) {
				tokens.add(place.getTokens().remove(0)); 
			}
		}
		for (Arc arc : getOutgoings()) {
			Place place = (Place) arc.getTarget();
			int count = arc.getWeight();
			for (int i = 0; i < count; i++) {
				Token token = (tokens.size() > 0) ? tokens.remove(0) :
					PetriFactory.eINSTANCE.createToken();
				token.setPlace(place);
				place.getTokens().add(token);
			}
		}
	}


	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case PetriPackage.TRANSITION__ENABLED:
				return isEnabled();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case PetriPackage.TRANSITION__ENABLED:
				return isEnabled() != ENABLED_EDEFAULT;
		}
		return super.eIsSet(featureID);
	}

} //TransitionImpl
